#ifndef _BOX3D_H_
#define _BOX3D_H_

#include <cmath>

template<typename T>
class Box3D
{
public:

	T x0, x1;
	T y0, y1;
	T z0, z1;

public:

	Box3D();

	Box3D(const Box3D& rhs);

	Box3D(T x0, T x1, T y0, T y1, T z0, T z1);

	virtual ~Box3D();

public:

	const Box3D& operator=(const Box3D& rhs);

public:

	template<class PolygonType>
	bool Intersect(PolygonType& polygon);

	T Volume();

};

template<typename T>
Box3D<T>::Box3D():x0(T()), x1(T()), y0(T()), y1(T()), z0(T()),z1(T())
{

}

template<typename T>
Box3D<T>::Box3D(const Box3D& rhs)
{
	this->x0 = rhs.x0;
	this->x1 = rhs.x1;

	this->y0 = rhs.y0;
	this->y1 = rhs.y1;

	this->z0 = rhs.z0;
	this->z1 = rhs.z1;
}

template<typename T>
Box3D<T>::Box3D(T x0, T x1, T y0, T y1, T z0, T z1)
{
	this->x0 = x0;
	this->x1 = x1;

	this->y0 = y0;
	this->y1 = y1;

	this->z0 = z0;
	this->z1 = z1;
}

template<typename T>
Box3D<T>::~Box3D()
{

}

template<typename T>
const Box3D<T>& Box3D<T>::operator=(const Box3D& rhs)
{
	this->x0 = rhs.x0;
	this->x1 = rhs.x1;

	this->y0 = rhs.y0;
	this->y1 = rhs.y1;

	this->z0 = rhs.z0;
	this->z1 = rhs.z1;
	
	return *this;
}

template<typename T>
template<class PolygonType>
bool Box3D<T>::Intersect(PolygonType& polygon)
{
	bool xInside = polygon.getPosition().x() >= this->x0 && polygon.getPosition().x() <= this->x1;
	bool yInside = polygon.getPosition().y() >= this->y0 && polygon.getPosition().y() <= this->y1;
	bool zInside = polygon.getPosition().z() >= this->z0 && polygon.getPosition().z() <= this->z1;
	return xInside && yInside && zInside;
}

template<typename T>
T Box3D<T>::Volume()
{
	using namespace std;
	return ( abs(x1 - x0) * abs(y1 - y0) * abs(z1 - z0) );
}

#endif // _BOX3D_H_
